package com.bbjob.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.UUID;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;

import com.github.junrar.Archive;
import com.github.junrar.rarfile.FileHeader;





public class FileUtil {
	private static final int buffer = 1024;

	/**
	 * �?测网络资源是否存�?
	 * 
	 * @param strUrl
	 * @return
	 */
	public static boolean isNetFileAvailable(String strUrl) {
		InputStream netFileInputStream = null;
		try {
			URL url = new URL(strUrl);
			URLConnection urlConn = url.openConnection();
			netFileInputStream = urlConn.getInputStream();
			if (null != netFileInputStream) {
				return true;
			} else {
				return false;
			}
		} catch (IOException e) {
			return false;
		} finally {
			try {
				if (netFileInputStream != null)
					netFileInputStream.close();
			} catch (IOException e) {
			}
		}
	}

	public static void clearPath(File file) {
		File[] files = file.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				File tmpfile = files[i];
				if (tmpfile.isDirectory()) {
					clearPath(tmpfile);
				} else {
					tmpfile.delete();
				}
			}
			file.delete();
		}
	}

	public static String getFileEncoding(File file) {
		String enc = Charset.forName("GBK").name();
        InputStream in= null;
        try {
            in = new FileInputStream(file);
            byte[] b = new byte[3];
            in.read(b);
            in.close();
            if (b[0] == -17 && b[1] == -69 && b[2] == -65) {
                enc = Charset.forName("UTF-8").name();
            }
        }  catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("文件编码格式�?:" + enc);
        return enc;
	}



	

	/**
	 * 解压zip文件
	 * 
	 * @param zipFilePath
	 * @param outputDirectory
	 *            输出目录
	 * @return
	 */
	public static boolean unzipFile(File zipFilePath, String outputDirectory) {
		boolean flag = false;
		String charset = FileUtil.getFileEncoding(zipFilePath);
		System.out.println(charset);
		ZipFile zipFile=null;
		try {
			zipFile = new ZipFile(zipFilePath, charset);
			Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
			createDirectory(outputDirectory, "");
			while (entries.hasMoreElements()) {
				 ZipArchiveEntry entry = entries.nextElement();
				String fileName = entry.getName();
				System.out.println("unzip " + fileName);
				if (entry.isDirectory()) {
					String name = fileName.trim();
					name = name.substring(0, name.length() - 1);
					File f = new File(outputDirectory + File.separator + name);
					if (!f.exists()) {
						f.mkdir();
					}

				} else {
					fileName = fileName.replace('\\', '/');
					if (fileName.indexOf("/") != -1) {
						createDirectory(outputDirectory, fileName.substring(0, fileName.lastIndexOf("/")));
						// fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
					}
					File f = new File(outputDirectory + File.separator + fileName);
					f.createNewFile();
					InputStream in = zipFile.getInputStream(entry);
					FileOutputStream out = new FileOutputStream(f);
					byte[] by = new byte[buffer];
					int c;
					while ((c = in.read(by)) != -1) {
						out.write(by, 0, c);
					}
					in.close();
					out.close();
					zipFile.close();
				}
			}
			flag = true;
			System.out.println("unzip finished");
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return flag;
	}

	public static void unRarFile3(File rarFile, String dstDirectoryPath) {
		File dstDiretory = new File(dstDirectoryPath);
		if (!dstDiretory.exists()) {// 目标目录不存在时，创建该文件�?
			dstDiretory.mkdirs();
		}
		Archive a = null;
		try {
			/*
			 * if(!"UTF-8".equals(FileUtil.getFileEncoding(rarFile))){ convert(rarFile,
			 * FileUtil.getFileEncoding(rarFile), "UTF-8"); }
			 */
			a = new Archive(rarFile);
			if (a != null) {
				// a.getMainHeader().print(); // 打印文件信息.
				FileHeader fh = a.nextFileHeader();
				while (fh != null) {
					// 防止文件名中文乱码问题的处理
					String fileName;
	                if (fh.isUnicode()) {
	                	fileName = fh.getFileNameW();
	                }else {
	                	fileName = fh.getFileNameString();
	                }
					
					fileName = fileName.replace("\\", "/");
					if (fh.isDirectory()) { // 文件�?
						File fol = new File(dstDirectoryPath + File.separator + fileName);
						fol.mkdirs();
					} else { // 文件
						File out = new File(dstDirectoryPath + File.separator + fileName.trim());
						try {
							if (!out.exists()) {
								if (!out.getParentFile().exists()) {// 相对路径可能多级，可能需要创建父目录.
									out.getParentFile().mkdirs();
								}
								out.createNewFile();
							}
							FileOutputStream os = new FileOutputStream(out);
							a.extractFile(fh, os);
							os.close();
						} catch (Exception ex) {
							ex.printStackTrace();
						}
					}
					fh = a.nextFileHeader();
				}
				a.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String args[]) {
		FileUtil.unRarFile3(new File("C:/Users/lenovo/Desktop/新建文件�?.rar"), "C:/Users/lenovo/Desktop/");
	}

	public static String getMD5(File f) {
		BigInteger bi = null;
		try {
			byte[] buffer = new byte[8192];
			int len = 0;
			MessageDigest md = MessageDigest.getInstance("MD5");
			FileInputStream fis = new FileInputStream(f);
			while ((len = fis.read(buffer)) != -1) {
				md.update(buffer, 0, len);
			}
			fis.close();
			byte[] b = md.digest();
			bi = new BigInteger(1, b);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bi.toString(16);
	}

	private static void createDirectory(String directory, String subDirectory) {
		String dir[];
		File fl = new File(directory);
		try {
			if (subDirectory == "" && fl.exists() != true) {
				fl.mkdir();
			} else if (subDirectory != "") {
				dir = subDirectory.replace('\\', '/').split("/");
				for (int i = 0; i < dir.length; i++) {
					File subFile = new File(directory + File.separator + dir[i]);
					if (subFile.exists() == false) {
						subFile.mkdir();
					}
					directory += File.separator + dir[i];
				}
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}

	/**
	 * 把指定文件或目录转换成指定的编码
	 * 
	 * @param file
	 *            要转换的文件或目�?
	 * @param fromCharsetName
	 *            源文件的编码
	 * @param toCharsetName
	 *            要转换的编码
	 * @throws Exception
	 */
	public static void convert(File file, String fromCharsetName, String toCharsetName) throws Exception {
		convert(file, fromCharsetName, toCharsetName, null);
	}

	/**
	 * 把指定文件或目录转换成指定的编码
	 * 
	 * @param file
	 *            要转换的文件或目�?
	 * @param fromCharsetName
	 *            源文件的编码
	 * @param toCharsetName
	 *            要转换的编码
	 * @param filter
	 *            文件名过滤器
	 * @throws Exception
	 */
	public static void convert(File file, String fromCharsetName, String toCharsetName, FilenameFilter filter)
			throws Exception {
		if (file.isDirectory()) {
			File[] fileList = null;
			if (filter == null) {
				fileList = file.listFiles();
			} else {
				fileList = file.listFiles(filter);
			}
			for (File f : fileList) {
				convert(f, fromCharsetName, toCharsetName, filter);
			}
		} else {
			if (filter == null || filter.accept(file.getParentFile(), file.getName())) {
				String fileContent = getFileContentFromCharset(file, fromCharsetName);
				saveFile2Charset(file, toCharsetName, fileContent);
			}
		}
	}

	/**
	 * 以指定编码方式读取文件，返回文件内容
	 * 
	 * @param file
	 *            要转换的文件
	 * @param fromCharsetName
	 *            源文件的编码
	 * @return
	 * @throws Exception
	 */
	public static String getFileContentFromCharset(File file, String fromCharsetName) throws Exception {
		if (!Charset.isSupported(fromCharsetName)) {
			throw new UnsupportedCharsetException(fromCharsetName);
		}
		InputStream inputStream = new FileInputStream(file);
		InputStreamReader reader = new InputStreamReader(inputStream, fromCharsetName);
		char[] chs = new char[(int) file.length()];
		reader.read(chs);
		String str = new String(chs).trim();
		reader.close();
		return str;
	}

	public static String getUUID() {
		String uuid = UUID.randomUUID().toString();
		uuid = uuid.replaceAll("-", "");
		return uuid.toUpperCase();
	}

	/**
	 * 以指定编码方式写文本文件，存在会覆盖
	 * 
	 * @param file
	 *            要写入的文件
	 * @param toCharsetName
	 *            要转换的编码
	 * @param content
	 *            文件内容
	 * @throws Exception
	 */
	public static void saveFile2Charset(File file, String toCharsetName, String content) throws Exception {
		if (!Charset.isSupported(toCharsetName)) {
			throw new UnsupportedCharsetException(toCharsetName);
		}
		OutputStream outputStream = new FileOutputStream(file);
		OutputStreamWriter outWrite = new OutputStreamWriter(outputStream, toCharsetName);
		outWrite.write(content);
		outWrite.close();
	}

	/**
	 * 获取不带后缀名的文件�?
	 * 
	 * @param file
	 * @return
	 */
	public static String getFileNameWithoutSuffix(File file) {
		String file_name = file.getName();
		return file_name.substring(0, file_name.lastIndexOf("."));
	}

	public static String getFileNameWithoutSuffix(String filename) {
		return filename.substring(0, filename.lastIndexOf("."));
	}

	public static String getFilePathWithoutSuffix(File file) {
		String file_path = file.getPath();
		return file_path.substring(0, file_path.lastIndexOf("."));
	}

	/**
	 * 获取文件后缀�?
	 * 
	 * @param file
	 * @return
	 */
	public static String getSuffix(File file) {
		String fileName = file.getName();
		String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
		return suffix;
	}

	/**
	 * 获取文件后缀�?
	 * 
	 * @param file
	 * @return
	 */
	public static String getSuffix(String filename) {
		String suffix = filename.substring(filename.lastIndexOf(".") + 1);
		return suffix;
	}

	//删除指定文件夹下的所有文�?
	public static boolean delAllFile(String path) {
		boolean flag = false;
		File file = new File(path);
		if (!file.exists()) {
			return flag;
		}
		if (!file.isDirectory()) {
			return flag;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				temp = new File(path + tempList[i]);
			} else {
				temp = new File(path + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				temp.delete();
			}
			if (temp.isDirectory()) {
				delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文�?
				delFolder(path + "/" + tempList[i]);// 再删除空文件�?
				flag = true;
			}
		}
		return flag;
	}

	//删除文件�?  
	public static void delFolder(String folderPath) {
		try {
			delAllFile(folderPath); // 删除完里面所有内�?
			String filePath = folderPath;
			filePath = filePath.toString();
			java.io.File myFilePath = new java.io.File(filePath);
			myFilePath.delete(); // 删除空文件夹
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
